from flask import session
from . import passport_bp
from flask import request,abort,make_response,jsonify,current_app
from info.utlis.captcha.captcha import captcha
from info.utlis.response_code import RET
from info import redis_store,constants, db
from info.models import User
from info.lib.yuntongxun.sms import CCP
import json,re,random
from datetime import datetime


@passport_bp.route('/register',methods=['post'])
def register():
    """用户注册接口"""
    """
    1.获取参数
        1.手机号码 用户填写的短信验证码 密码（未加密）
    2.校验参数
        2.1 非空判断
        2.2 手机号码格式判断
    3.逻辑处理
        3.1 根据手机号码拼接SMS_18520340804这个key去redis获取真实短信验证码
        3.2 对比用户添加的短信验证码和真实的短信验证码对比
        3.3 一致：根据User模型创建用户对象，保存到数据库
        3.4 一般：用户注册成功 第一次都会给用户自动登录，使用session存储用户信息
    4.返回值处理
    """
    params_dict = request.json
    mobile = params_dict.get("mobile")
    smscode = params_dict.get("smscode")
    password = params_dict.get("password")
    # 2.1 非空判断
    if not all([mobile, smscode, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    # 2.2 手机号码格式判断
    if not re.match('^1[356789][0-9]{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机格式错误")
    # 3.逻辑处理
        #3.1 根据手机号码拼接SMS_18520340804这个key去redis获取真实短信验证码
    try:
        real_sms_code = redis_store.get("smscode_%s"%mobile)
        if real_sms_code:
            redis_store.delete("smscode_%s"%mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="查询短信验证码异常")
    if not real_sms_code:
        return jsonify(errno=RET.NODATA,errmsg="短信验证码过期")
        #3.2 对比用户添加的短信验证码和真实的短信验证码对比
    if real_sms_code != smscode:
        return jsonify(errno=RET.PARAMERR,errmsg="短信验证码填写错误")
        #3.3 一致：根据User模型创建用户对象，保存到数据库
    user = User()
    user.mobile = mobile
    user.nick_name = mobile
    # TODO:需要将密码加密后赋值给password_hash
    user.password = password
    user.last_login = datetime.now()
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg="")
    #3.4 一般：用户注册成功 第一次都会给用户自动登录，使用session存储用户信息
    session["user_id"] = user.id
    session["mobile"] = user.mobile
    session["nick_name"] = user.mobile

    #4.返回值处理
    return jsonify(errno=RET.OK,errmsg="注册成功")

@passport_bp.route('/login',methods=['post'])
def login():
    """登录接口"""
    """
    1.获取参数
        1.1 手机号码 密码（未加密的）
    2.校验参数
        2.1 非空判断
        2.2 手机号码格式
    3.逻辑处理
        3.1 根据手机号码查询用户对象
        3.2 对比用户填写的密码和用户对象中密码是否一致
        3.3 一致：记录最后一次登录时间 使用session记录用户登录信息
    4.返回值处理
    """
    params_dict = request.json
    mobile = params_dict.get("mobile")
    password = params_dict.get("password")
    # 2.1 非空判断
    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    # 2.2 手机号码格式判断
    if not re.match('^1[356789][0-9]{9}$', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机格式错误")

    #3.逻辑处理
        #3.1 根据手机号码查询用户对象
    try:
        user = User.query.filter(User.mobile==mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="查询用户对象异常")
    if not user:
        return jsonify(errno=RET.NODATA,errmsg="用户不存在")
        #3.2 对比用户填写的密码和用户对象中密码是否一致
    if not user.check_passowrd(password):
        return jsonify(errno=RET.PWDERR,errmsg="密码错误")

    #3.3 一致：记录最后一次登录时间 使用session记录用户登录信息
    session["user_id"]=user.id
    session["mobile"]=user.mobile
    session["nick_name"]=user.mobile

    user.last_login = datetime.now()
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="用户对象保存到数据库异常")
    return jsonify(errno=RET.OK,errmsg="登录成功")

@passport_bp.route('/login_out',methods=['post'])
def login_out():
    session.pop("user_id")
    session.pop("mobile")
    session.pop("nick_name")
    return jsonify(errno=RET.OK,errmsg="退出成功")

@passport_bp.route('/image_code')
def image_code():
    # 1.获取参数
    # 1.1获取前端传上来
    imageCodeId = request.args.get("imageCodeId", "")
    # 2.校验参数
    if not imageCodeId:
        abort(404)

    name,text,image = captcha.generate_captcha()

    try:
        redis_store.set("imagecode_%s"%imageCodeId,text,ex=constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        abort(e)

    response = make_response(image)
    response.headers["Content-Type"] = "image/html"
    return response


@passport_bp.route('/sms_code',methods=['post'])
def sms_code():
    parms_dict = request.json
    mobile = parms_dict.get("mobile")
    # 用户填写的图片验证码值
    image_code = parms_dict.get("image_code")
    image_code_id = parms_dict.get("image_code_id")
    # 判断是否空值
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数不足")
    # 判断手机号是否输错
    if not re.match('1[35789][0-9]{9}',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg="请正确填写手机号")
    # 取到数据库中image_code的真实值
    try:
        image_val = redis_store.get("imagecode_%s"%image_code_id)
        if image_val:
            redis_store.delete(image_val)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="查询该数据异常")

    if not image_val:
        return jsonify(errno=RET.NODATA,errmsg="图片验证码过期了")

    if image_val.lower() != image_code.lower():
        return jsonify(errno=RET.DATAERR,errmsg="验证码填写错误")

    try:
        user = User.query.filter(User.mobile==mobile).first()
        if user:
            return jsonify(errno=RET.DATAEXIST,errmsg="该手机号已经注册过")
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="查询手机号异常")

    # 发送短信验证码
    sms_code = random.randint(0,999999)
    sms_code = '%06d'%sms_code
    result = CCP().send_template_sms(mobile,[sms_code, constants.SMS_CODE_REDIS_EXPIRES/60], 1)
    if result != 0:
        return jsonify(errno=RET.PARAMERR,errmsg="发送短信失败")
    try:
        redis_store.set("smscode_%s"%mobile,sms_code,ex=constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg="保存短信验证码到数据库错误")

    return jsonify(errno=RET.OK,errmsg="发送短信成功")
